﻿using Abp;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Json;
using Abp.Runtime.Session;
using Castle.Core.Logging;
using JetBrains.Annotations;
using Mt.Site.Core.Base.Reflection;
using Mt.Site.Core.DiyContent.Form.Entities;
using Mt.Site.Core.Organizations.UserCache;
using Mt.Site.Core.Organizations.UserCache.Models;
using Mt.Site.Core.VersionBackup.Entities;
using Mt.Site.Core.WorkFlows.Design.DiyForm;
using Mt.Site.Core.WorkFlows.Diy;
using Mt.Site.Core.WorkFlows.Enum;
using Mt.Site.Core.WorkFlows.Process.Entities;
using Mt.Site.Core.WorkFlows.Process.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Mt.Site.Core.WorkFlows.Process.Stores
{
    public class WorkFlowFormDataStore : IWorkFlowFormDataStore, ITransientDependency
    {
        private readonly IRepository<BackupBody, long> _backupBodyRepository;

        private readonly IRepository<WorkFlowPaperData, Guid> _workFlowPaperDataRepository;
        private readonly IRepository<WorkFlowPaperListCtrlData, long> _workFlowPaperListCtrlDataRepository;
        private readonly IUserAndUnitFinder _userAndUnitFinder;
        private readonly IWorkFlowHelper _workFlowHelper;

        public IAbpSession AbpSession { get; set; }

        public ILogger Logger { get; set; }

        public IQueryable<WorkFlowPaperData> WorkFlowPaperData => _workFlowPaperDataRepository.GetAll();

        private readonly IWorkFlowPluginManager _workFlowPluginManager;
        private readonly IIocResolver _iocResolver;

        public WorkFlowFormDataStore(
            IRepository<WorkFlowPaperData, Guid> workFlowPaperDataRepository,
            IRepository<WorkFlowPaperListCtrlData, long> workFlowPaperListCtrlDataRepository,
            IRepository<BackupBody, long> backupBodyRepository,
            IUserAndUnitFinder userAndUnitFinder,
            IWorkFlowHelper workFlowHelper,
            IIocResolver iocResolver,
            IWorkFlowPluginManager workFlowPluginManager)
        {
            _workFlowPaperDataRepository = workFlowPaperDataRepository;
            _workFlowPaperListCtrlDataRepository = workFlowPaperListCtrlDataRepository;
            _backupBodyRepository = backupBodyRepository;
            _userAndUnitFinder = userAndUnitFinder;
            _workFlowHelper = workFlowHelper;
            _iocResolver = iocResolver;
            _workFlowPluginManager = workFlowPluginManager;

            AbpSession = NullAbpSession.Instance;
            Logger = NullLogger.Instance;
        }

        public async Task<GetFormDataOutput> GetFormDataForEditAsync(IWorkFlowManager workFlowManager)
        {
            var workflow = workFlowManager.CurrentPaper.WorkFlow;
            var curentNodeId = workFlowManager.NodeId;
            var paperId = workFlowManager.PaperId;
            var actionState = await workFlowManager.CheckActionStateAsync();

            FormConfigItem[] formConfig = workflow.Definition.FormConfig;
            Dictionary<string, FormConfigItem[]> FormListCtrlConfig = workflow.Definition.FormListCtrlConfig;
            Guid workFlowId = workflow.Definition.WorkFlowId;

            var result = new GetFormDataOutput
            {
                Data = new Dictionary<string, object>(),
                FieldDisabled = new Dictionary<string, bool>()
            };
            var currentUserInfo = await _userAndUnitFinder.GetUserInfoAsync(AbpSession.GetUserId());
            var workFlowPaperDataList = await _workFlowPaperDataRepository.GetAllListAsync(c => c.PaperId == paperId);
            var largeStrDataList = await _backupBodyRepository.GetAllListAsync(c => c.ContentId == paperId);

            foreach (var field in formConfig)
            {
                var pascalCaseKey = field.FieldName.ToPascalCase();
                var camelCaseKey = field.FieldName.ToCamelCase();
                
                //本字段是否可编辑（因为这里有一些字段只是用来做状态位，如标记某个控件是否生效，所以数据读取时不做细节过滤）
                bool canEdit = false;
                if (field.NodeIdList.Contains(curentNodeId) && actionState == ActionState.Todo)
                {
                    canEdit = true;
                    result.FieldDisabled.Add(camelCaseKey, false);
                }
                else
                {
                    result.FieldDisabled.Add(camelCaseKey, true);
                }

                ValueWraper _val;
                Guid? dataId = null;
                if(field.FieldType == FieldType.Content)
                {
                    var data = largeStrDataList.FirstOrDefault(c => c.FieldName == pascalCaseKey);
                    _val = (data == null ? null : new ValueWraper(data.Value));
                }
                else
                {
                    var data = workFlowPaperDataList.FirstOrDefault(c => c.FieldName == pascalCaseKey);
                    _val = (data == null ? null : new ValueWraper(data.Value));
                    dataId = data?.Id;
                }

                if (_val != null)
                {
                    if (field.FieldType != FieldType.ListCtrl)
                    {
                        //TODO: 其他数据类型及空值的转化
                        if(field.FieldType == FieldType.Boolean)
                        {
                            var _tval = _val.Object;
                            result.Data.Add(camelCaseKey, _tval == "true"? true: false);
                        }
                        else
                        {
                            result.Data.Add(camelCaseKey, _val.Object);
                        }
                    }
                    else
                    {
                        //拉取列表控件配置 ( workFlowPaperData.Value ==field.CustomData 为当前列表控件的配置数据id)
                        if (FormListCtrlConfig.TryGetValue(_val.Object, out FormConfigItem[] listCtrlConfig))
                        {
                            await GetListCtrlDataForEdit(result, camelCaseKey, dataId.Value, listCtrlConfig);
                        }
                        else
                        {
                            //对应的list控件的id无效
                            Logger.Error($"list控件的id无效,流程Id:{workFlowId},list控件id:{_val.Object}");
                        }
                    }
                }
                else
                {
                    if (canEdit)
                    {
                        //添加默认值
                        var defaultValue = await GetDefaultValue(field, currentUserInfo, paperId, workflow);
                        result.Data[camelCaseKey] = defaultValue;
                    }
                }
            }

            return result;
        }

        public async Task<List<FormDataItemDescription>> GetFieldPermissionAsync(
            [NotNull]IWorkflowDefinition workflow,
            Guid curentNodeId,
            IWorkFlowManager workFlowManager)
        {
            FormConfigItem[] formConfig = workflow.Definition.FormConfig;

            var result = new List<FormDataItemDescription>();

            foreach (var field in formConfig)
            {
                var propertieKey = field.FieldName.ToPascalCase();
                var propertieKeyCamelCase = field.FieldName.ToCamelCase();

                if (field.NodeIdList.Contains(curentNodeId))
                {
                    result.Add(new FormDataItemDescription
                    {
                        PascalCaseKey = propertieKey,
                        CamelCaseKey = propertieKeyCamelCase,
                        CanEdit = true,
                        IsListCtrl = (field.FieldType == FieldType.ListCtrl)
                    });
                }
            }

            if(workFlowManager != null)
            {
                return await workFlowManager.WorkFlowNodePluginFunction.FilterFormFieldsPermissionAsync(result, workFlowManager);
            }

            return  result;
        }

        private async Task GetListCtrlDataForEdit(GetFormDataOutput result, string propertieKeyCamelCase, Guid workFlowPaperDataId, FormConfigItem[] listCtrlConfig)
        {
            var listData = new List<Dictionary<string, object>>();
            //拉取列表数据
            var listCtrlDataList = (await _workFlowPaperListCtrlDataRepository.GetAllListAsync(c => c.RelateId == workFlowPaperDataId))
                .OrderBy(c => c.Order);
            foreach (var listCtrlData in listCtrlDataList)
            {
                var ctrlDataItem = new Dictionary<string, object>();
                foreach (var listCtrlItem in listCtrlConfig)
                {
                    var listCtrlItemKey = listCtrlItem.FieldName.ToPascalCase();
                    var value = TypeHelper.GetPropertyValue(listCtrlData, listCtrlItemKey);
                    if (value != null)
                    {
                        ctrlDataItem.Add(listCtrlItemKey.ToCamelCase(), value);
                    }
                }
                ctrlDataItem["id"] = listCtrlData.Id;
                listData.Add(ctrlDataItem);
            }
            result.Data.Add(propertieKeyCamelCase, listData.ToJsonString());
        }

        public async Task UpdateAsync(
            Dictionary<string, string> values,
            IWorkFlowManager workFlowManager)
        {
            var workflow = workFlowManager.CurrentPaper.WorkFlow;
            var curentNodeId = workFlowManager.NodeId;
            var paperId = workFlowManager.PaperId;

            FormConfigItem[] formConfig = workflow.Definition.FormConfig;
            Dictionary<string, FormConfigItem[]> FormListCtrlConfig = workflow.Definition.FormListCtrlConfig;
            Guid workFlowId = workflow.Definition.WorkFlowId;

            var fieldDescriptionList = (await GetFieldPermissionAsync(workflow, curentNodeId, workFlowManager))
                .Select(c => c.PascalCaseKey)
                .ToList();

            var workFlowPaperDataList = await _workFlowPaperDataRepository.GetAllListAsync(c => c.PaperId == paperId);
            var largeStrDataList = await _backupBodyRepository.GetAllListAsync(c => c.ContentId == paperId);

            var checker = new ContentDataChecher();
            var newValues = values.Select(c => new NameValue(c.Key.ToPascalCase(), c.Value));
            var oldFields = workFlowPaperDataList.Select(c => c.FieldName).ToList();
            oldFields.AddRange(largeStrDataList.Select(c => c.FieldName));

            // 1 原来没有的(可能前几个步骤里一直不可编辑)，要添加
            foreach (var newValue in newValues.Where(p => !oldFields.Contains(p.Name) && fieldDescriptionList.Contains(p.Name)))
            {
                await AddWhenNotExisting(paperId, workFlowId, curentNodeId, formConfig, newValue, FormListCtrlConfig, checker, workflow);
            }

            foreach (var item in workFlowPaperDataList)
            {
                if (fieldDescriptionList.Contains(item.FieldName))
                {
                    await UpdateWhenExisting(paperId, workFlowId, curentNodeId, formConfig, newValues, item, FormListCtrlConfig, checker, workflow);
                }
            }
            foreach (var item in largeStrDataList)
            {
                if (fieldDescriptionList.Contains(item.FieldName))
                {
                    UpdateWhenExisting(curentNodeId, formConfig, newValues, item, checker, workflow);
                }
            }
        }

        private async Task AddWhenNotExisting(
            Guid paperId, Guid workFlowId, Guid curentNodeId, 
            FormConfigItem[] formConfig, 
            NameValue newValue,
            Dictionary<string, FormConfigItem[]> FormListCtrlConfig,
            ContentDataChecher checker,
            IWorkflowDefinition workflow)
        {
            var fieldConfig = formConfig.FirstOrDefault(c => c.FieldName.ToPascalCase() == newValue.Name);
            if (fieldConfig != null && fieldConfig.NodeIdList.Contains(curentNodeId))
            {
                if (fieldConfig.FieldType != FieldType.ListCtrl)
                {
                    var val = checker.Check(fieldConfig.Security, newValue.Value, fieldConfig.DisplayName, fieldConfig.FieldType);
                    if (fieldConfig.FieldType == FieldType.Content)
                    {
                        var data = new BackupBody { ContentId = paperId, FieldName = newValue.Name, Value = val };
                        await _backupBodyRepository.InsertAsync(data);
                    }
                    else
                    {
                        await SaveReferNumber(paperId, newValue, fieldConfig, workflow);

                        var data = new WorkFlowPaperData { PaperId = paperId, FieldName = newValue.Name, Value = val };
                        await _workFlowPaperDataRepository.InsertAsync(data);
                    }
                }
                else
                {
                    var data = new WorkFlowPaperData { PaperId = paperId, FieldName = newValue.Name, Value = fieldConfig.CustomData };
                    data.Id = Guid.NewGuid();
                    await _workFlowPaperDataRepository.InsertAsync(data);
                    await AddOrUpdateListCtrlData(paperId, workFlowId, newValue, FormListCtrlConfig, fieldConfig, checker, data.Id);
                }
            }
        }

        private async Task UpdateWhenExisting(
            Guid paperId, Guid workFlowId, Guid curentNodeId, 
            FormConfigItem[] formConfig, 
            IEnumerable<NameValue> newValues, 
            WorkFlowPaperData item,
            Dictionary<string, FormConfigItem[]> FormListCtrlConfig,
            ContentDataChecher checker,
            IWorkflowDefinition workflow)
        {
            var newValue = newValues.FirstOrDefault(c => c.Name == item.FieldName);
            //修改
            if (newValue != null)
            {
                var fieldConfig = formConfig.FirstOrDefault(c => c.FieldName.ToPascalCase() == item.FieldName);
                if (fieldConfig != null && fieldConfig.NodeIdList.Contains(curentNodeId))
                {
                    if (fieldConfig.FieldType != FieldType.ListCtrl)
                    {
                        var val = checker.Check(fieldConfig.Security, newValue.Value, fieldConfig.DisplayName, fieldConfig.FieldType);
                        await SaveReferNumber(paperId, newValue, fieldConfig, workflow);
                        item.Value = val;
                    }
                    else
                    {
                        item.Value = fieldConfig.CustomData;
                        await AddOrUpdateListCtrlData(paperId, workFlowId, newValue, FormListCtrlConfig, fieldConfig, checker, item.Id);
                    }
                }
            }
            else
            {
                //新提交的数据中没有的（可能表单被编辑过）
            }
        }
        private void UpdateWhenExisting(
            Guid curentNodeId, 
            FormConfigItem[] formConfig, 
            IEnumerable<NameValue> newValues,
            BackupBody item,
            ContentDataChecher checker,
            IWorkflowDefinition workflow)
        {
            var newValue = newValues.FirstOrDefault(c => c.Name == item.FieldName);
            //修改
            if (newValue != null)
            {
                var fieldConfig = formConfig.FirstOrDefault(c => c.FieldName.ToPascalCase() == item.FieldName);
                if (fieldConfig != null && fieldConfig.NodeIdList.Contains(curentNodeId))
                {
                    var val = checker.Check(fieldConfig.Security, newValue.Value, fieldConfig.DisplayName, fieldConfig.FieldType);
                    item.Value = val;
                }
            }
            else
            {
                //新提交的数据中没有的（可能表单被编辑过）
            }
        }

        private async Task AddOrUpdateListCtrlData(
            Guid paperId, Guid workFlowId,
            NameValue newValue,
            Dictionary<string, FormConfigItem[]> FormListCtrlConfig, FormConfigItem fieldConfig,
            ContentDataChecher checker, 
            Guid relateId)
        {
            try
            {
                //拉取列表控件配置 ( workFlowPaperData.Value ==field.CustomData 为当前列表控件的配置数据id)
                if (FormListCtrlConfig.TryGetValue(fieldConfig.CustomData, out FormConfigItem[] listCtrlConfig))
                {
                    var listCtrDataList = newValue.Value.FromJsonString<List<Dictionary<string, string>>>();
                    var oldListCtrlDataList = await _workFlowPaperListCtrlDataRepository.GetAllListAsync(c => c.RelateId == relateId);
                    foreach (var listCtrData in listCtrDataList)
                    {
                        if (listCtrData.TryGetValue("id", out string idStr) && long.TryParse(idStr, out long id))
                        {
                            //修改
                            var oldListCtrlData = oldListCtrlDataList.FirstOrDefault(c=>c.Id == id);
                            if(oldListCtrlData != null)
                            {
                                foreach (var listCtrlField in listCtrlConfig)
                                {
                                    var propertieKey = listCtrlField.FieldName.ToPascalCase();
                                    var propertieKeyCamelCase = listCtrlField.FieldName.ToCamelCase();
                                    if(listCtrData.ContainsKey(propertieKeyCamelCase))
                                    {
                                        var val = checker.Check(listCtrlField.Security, listCtrData[propertieKeyCamelCase], listCtrlField.DisplayName, listCtrlField.FieldType);
                                        TypeHelper.SetPropertyValue(oldListCtrlData, propertieKey, val);
                                    }
                                }
                            }
                        }
                        else
                        {
                            //新建
                            var newListCtrlData = new WorkFlowPaperListCtrlData();
                            newListCtrlData.RelateId = relateId;
                            foreach (var listCtrlField in listCtrlConfig)
                            {
                                var propertieKey = listCtrlField.FieldName.ToPascalCase();
                                var propertieKeyCamelCase = listCtrlField.FieldName.ToCamelCase();
                                if (listCtrData.ContainsKey(propertieKeyCamelCase))
                                {
                                    var val = checker.Check(listCtrlField.Security, listCtrData[propertieKeyCamelCase], listCtrlField.DisplayName, listCtrlField.FieldType);
                                    TypeHelper.SetPropertyValue(newListCtrlData, propertieKey, val);
                                }
                            }
                            await _workFlowPaperListCtrlDataRepository.InsertAsync(newListCtrlData);
                        }
                    }

                    //移除删除的行
                    var idList = listCtrDataList.Select(n =>
                    {
                        if (n.TryGetValue("id", out string idStr) && long.TryParse(idStr, out long id))
                        {
                            return id;
                        }
                        else
                        {
                            return 0;
                        }
                    });
                    foreach (var oldListCtrlData in oldListCtrlDataList.Where(p => !idList.Contains(p.Id)))
                    {
                        await _workFlowPaperListCtrlDataRepository.DeleteAsync(oldListCtrlData);
                    }
                }
                else
                {
                    //对应的list控件的id无效
                    Logger.Error($"list控件的id无效,流程Id:{workFlowId},list控件id:{fieldConfig.CustomData}");
                }
            }
            catch
            {
                Logger.Error($"表单中的列表控件数据解析出错, workFlowId:{workFlowId},paperId:{paperId},data:{newValue.Value }");
            }
        }

        private async Task<object> GetDefaultValue(FormConfigItem formItemConfig, UserInfoDto userInfo, Guid paperId, IWorkflowDefinition workflow)
        {
            var type = formItemConfig.FieldType;
            var defaultValue = formItemConfig.DefaultValue;

            if (type == FieldType.Boolean)
            {
                bool val = false;
                bool.TryParse(defaultValue, out val);
                return val;
            }
            else if (type == FieldType.DateTime)
            {
                //为避免时区的差异，保存时间戳格式，0代表没有赋值
                if (!defaultValue.IsNullOrEmpty())
                {
                    if (long.TryParse(defaultValue,out long defautltDateTime))
                    {
                        //具体的默认日期（需传入时间戳）
                        return defautltDateTime;
                    }
                    else
                    {
                        //yyyy-MM-dd,前者供服务端获取默认时间时使用
                        try
                        {
                            var formatStr = formItemConfig.CustomData;
                            return DateTime.Parse(DateTime.Now.ToString(formatStr)).ToLocalTime().ToUnixTimeByMilliseconds();
                        }
                        catch
                        {
                            return DateTime.Now.ToLocalTime().ToUnixTimeByMilliseconds();
                        }
                    }
                }
                return 0; 
            }
            else if (type == FieldType.DateTime2)
            {
                //返回字符串类型
                if (!defaultValue.IsNullOrEmpty())
                {
                    if (DateTime.TryParse(defaultValue, out DateTime defautltDateTime))
                    {
                        //具体的默认日期（需传入时间戳）
                        return defaultValue;
                    }
                    else
                    {
                        //yyyy-MM-dd,前者供服务端获取默认时间时使用
                        try
                        {
                            var formatStr = formItemConfig.CustomData;
                            return DateTime.Now.ToString(formatStr);
                        }
                        catch
                        {
                            return DateTime.Now.ToString("yyyy-MM-dd");
                        }
                    }
                }
                return "";
            }
            else if (type == FieldType.Number)
            {
                decimal val = 0;
                decimal.TryParse(defaultValue, out val);
                return val;
            }
            else
            {
                return await GetFuncValue(defaultValue, userInfo, paperId, workflow);
            }
        }
        private async Task<string> GetFuncValue(string defaultValue, UserInfoDto userInfo, Guid paperId, IWorkflowDefinition workflow)
        {
            switch (defaultValue)
            {
                case "[#经办人姓名#]":
                    return userInfo.UserName;
                case "[#经办人部门#]":
                    return userInfo.MainOrgnzation?.Name;
                case "[#文号#]":
                    using(var plugin = _workFlowPluginManager.GetWorkFlowDiyFunction(workflow, _iocResolver))
                    {
                        return await plugin.Object.GetWenhaoAsync(_workFlowHelper, paperId, workflow.Definition.WorkFlowId);
                    }
                default:
                    return defaultValue;
            }
        }

        private async Task SaveReferNumber(Guid paperId, NameValue newValue, FormConfigItem fieldConfig,
            IWorkflowDefinition workflow)
        {
            if (fieldConfig.DefaultValue == "[#文号#]")
            {
                using (var plugin = _workFlowPluginManager.GetWorkFlowDiyFunction(workflow, _iocResolver))
                {
                    await plugin.Object.TrySaveWenhaoAsync(_workFlowHelper, paperId, newValue.Value, fieldConfig, workflow);
                }
            }
        }

        public async Task<GetFormDataOutput> GetFormDataForSuperEditAsync(
            Guid paperId, IWorkflowDefinition workflow, Guid curentNodeId, long authorUserId)
        {
            FormConfigItem[] formConfig = workflow.Definition.FormConfig;
            Dictionary<string, FormConfigItem[]> FormListCtrlConfig = workflow.Definition.FormListCtrlConfig;
            Guid workFlowId = workflow.Definition.WorkFlowId;

            return await GetFormDataAsync(true, paperId, workFlowId, curentNodeId, formConfig, FormListCtrlConfig, authorUserId);
        }

        public async Task SuperUpdateAsync(Dictionary<string, string> values, Guid paperId, IWorkflowDefinition workflow, Guid curentNodeId)
        {
            FormConfigItem[] formConfig = workflow.Definition.FormConfig;
            Dictionary<string, FormConfigItem[]> FormListCtrlConfig = workflow.Definition.FormListCtrlConfig;
            Guid workFlowId = workflow.Definition.WorkFlowId;

            var workFlowPaperDataList = await _workFlowPaperDataRepository.GetAllListAsync(c => c.PaperId == paperId);
            var largeStrDataList = await _backupBodyRepository.GetAllListAsync(c => c.ContentId == paperId);

            var checker = new ContentDataChecher();
            var newValues = values.Select(c => new NameValue(c.Key.ToPascalCase(), c.Value));
            var oldFields = workFlowPaperDataList.Select(c => c.FieldName).ToList();
            oldFields.AddRange(largeStrDataList.Select(c => c.FieldName));

            // 1 原来没有的(可能前几个步骤里一直不可编辑)，要添加
            foreach (var newValue in newValues.Where(p => !oldFields.Contains(p.Name)))
            {
                var fieldConfig = formConfig.FirstOrDefault(c => c.FieldName.ToPascalCase() == newValue.Name);
                if (fieldConfig != null && !fieldConfig.AdminCanNotEdit)
                {
                    if (fieldConfig.FieldType != FieldType.ListCtrl)
                    {
                        var val = checker.Check(fieldConfig.Security, newValue.Value, fieldConfig.DisplayName, fieldConfig.FieldType);

                        if (fieldConfig.FieldType == FieldType.Content)
                        {
                            var data = new BackupBody { ContentId = paperId, FieldName = newValue.Name, Value = val };
                            await _backupBodyRepository.InsertAsync(data);
                        }
                        else
                        {
                            await SaveReferNumber(paperId, newValue, fieldConfig, workflow);

                            var data = new WorkFlowPaperData { PaperId = paperId, FieldName = newValue.Name, Value = val };
                            await _workFlowPaperDataRepository.InsertAsync(data);
                        }
                    }
                    else
                    {
                        var data = new WorkFlowPaperData { PaperId = paperId, FieldName = newValue.Name, Value = fieldConfig.CustomData };
                        data.Id = Guid.NewGuid();
                        await _workFlowPaperDataRepository.InsertAsync(data);
                        await AddOrUpdateListCtrlData(paperId, workFlowId, newValue, FormListCtrlConfig, fieldConfig, checker, data.Id);
                    }
                }
            }

            foreach (var item in workFlowPaperDataList)
            {
                var newValue = newValues.FirstOrDefault(c => c.Name == item.FieldName);
                //修改
                if (newValue != null)
                {
                    var fieldConfig = formConfig.FirstOrDefault(c => c.FieldName.ToPascalCase() == item.FieldName);
                    if (fieldConfig != null && !fieldConfig.AdminCanNotEdit)
                    {
                        if (fieldConfig.FieldType != FieldType.ListCtrl)
                        {
                            var val = checker.Check(fieldConfig.Security, newValue.Value, fieldConfig.DisplayName, fieldConfig.FieldType);
                            await SaveReferNumber(paperId, newValue, fieldConfig, workflow);
                            item.Value = val;
                        }
                        else
                        {
                            item.Value = fieldConfig.CustomData;
                            await AddOrUpdateListCtrlData(paperId, workFlowId, newValue, FormListCtrlConfig, fieldConfig, checker, item.Id);
                        }
                    }
                }
            }

            foreach (var item in largeStrDataList)
            {
                var newValue = newValues.FirstOrDefault(c => c.Name == item.FieldName);
                //修改
                if (newValue != null)
                {
                    var fieldConfig = formConfig.FirstOrDefault(c => c.FieldName.ToPascalCase() == item.FieldName);
                    if (fieldConfig != null && !fieldConfig.AdminCanNotEdit)
                    {
                        var val = checker.Check(fieldConfig.Security, newValue.Value, fieldConfig.DisplayName, fieldConfig.FieldType);
                        item.Value = val;
                    }
                }
            }
        }


        public async Task<GetFormDataOutput> GetFormDataForReadOnlyAsync(
            Guid paperId, IWorkflowDefinition workflow, Guid curentNodeId, long authorUserId)
        {
            FormConfigItem[] formConfig = workflow.Definition.FormConfig;
            Dictionary<string, FormConfigItem[]> FormListCtrlConfig = workflow.Definition.FormListCtrlConfig;
            Guid workFlowId = workflow.Definition.WorkFlowId;

            var data = await GetFormDataAsync(false, paperId, workFlowId, curentNodeId, formConfig, FormListCtrlConfig, authorUserId);

            using (var plugin = _workFlowPluginManager.GetWorkFlowDiyFunction(workflow, _iocResolver))
            {
                await plugin.Object.AfterGetDataForReadOnlyAsync(data);
            }

            return data;
        }

        //管理员or打印页等查看表单数据
        private async Task<GetFormDataOutput> GetFormDataAsync(
            bool isSuperEditer,
            Guid paperId, Guid workFlowId, Guid curentNodeId, FormConfigItem[] formConfig, Dictionary<string, FormConfigItem[]> FormListCtrlConfig, long authorUserId)
        {
            var result = new GetFormDataOutput
            {
                Data = new Dictionary<string, object>(),
                FieldDisabled = new Dictionary<string, bool>()
            };
            var currentUserInfo = await _userAndUnitFinder.GetUserInfoAsync(authorUserId);
            var workFlowPaperDataList = await _workFlowPaperDataRepository.GetAllListAsync(c => c.PaperId == paperId);
            var largeStrDataList = await _backupBodyRepository.GetAllListAsync(c => c.ContentId == paperId);

            foreach (var field in formConfig)
            {
                var propertieKey = field.FieldName.ToPascalCase();
                var propertieKeyCamelCase = field.FieldName.ToCamelCase();
                //本字段是否可编辑
                bool canEdit = isSuperEditer;
                if (canEdit)
                {
                    if (field.AdminCanNotEdit)
                    {
                        canEdit = false;
                    }
                }
                result.FieldDisabled.Add(propertieKeyCamelCase, !canEdit);

                ValueWraper _val;
                Guid? dataId = null;
                if (field.FieldType == FieldType.Content)
                {
                    var data = largeStrDataList.FirstOrDefault(c => c.FieldName == propertieKey);
                    _val = (data == null ? null : new ValueWraper(data.Value));
                }
                else
                {
                    var data = workFlowPaperDataList.FirstOrDefault(c => c.FieldName == propertieKey);
                    _val = (data == null ? null : new ValueWraper(data.Value));
                    dataId = data?.Id;
                }

                if (_val != null)
                {
                    if (field.FieldType != FieldType.ListCtrl)
                    {
                        result.Data.Add(propertieKeyCamelCase, _val.Object);
                    }
                    else
                    {
                        //拉取列表控件配置 ( workFlowPaperData.Value ==field.CustomData 为当前列表控件的配置数据id)
                        if (FormListCtrlConfig.TryGetValue(_val.Object, out FormConfigItem[] listCtrlConfig))
                        {
                            await GetListCtrlDataForEdit(result, propertieKeyCamelCase, dataId.Value, listCtrlConfig);
                        }
                        else
                        {
                            //对应的list控件的id无效
                            Logger.Error($"list控件的id无效,流程Id:{workFlowId},list控件id:{_val.Object}");
                        }
                    }
                }
            }

            return result;
        }
   
    
    
        public async Task<Dictionary<string,string>> GetSpecialFieldAsync(List<string> fieldName, Guid paperId)
        {
            var workFlowPaperDataList = await _workFlowPaperDataRepository.GetAllListAsync(c => c.PaperId == paperId && fieldName.Contains(c.FieldName));
            return workFlowPaperDataList.ToDictionary(c => c.FieldName, c => c.Value);
        }
        public async Task<Dictionary<string, string>> GetAllFieldAsync(Guid paperId)
        {
            var workFlowPaperDataList = await _workFlowPaperDataRepository.GetAllListAsync(c => c.PaperId == paperId);
            return workFlowPaperDataList.ToDictionary(c => c.FieldName, c => c.Value);
        }
        public async Task<string> GetSpecialFieldAsync(string fieldName, Guid paperId)
        {
            var entity = await _workFlowPaperDataRepository.FirstOrDefaultAsync(c => c.PaperId == paperId && c.FieldName == fieldName);
            return entity?.Value;
        }

        public async Task UpdateSpecialFieldAsync(string fieldName, Guid paperId, string value)
        {
            var entity = await _workFlowPaperDataRepository.FirstOrDefaultAsync(c => c.PaperId == paperId && c.FieldName == fieldName);
            if (entity != null)
            {
                entity.Value = value;
                await _workFlowPaperDataRepository.UpdateAsync(entity);
            }
        }
        public async Task UpdateOrInsertSpecialFieldAsync(string fieldName, Guid paperId, string value)
        {
            var entity = await _workFlowPaperDataRepository.FirstOrDefaultAsync(c => c.PaperId == paperId && c.FieldName == fieldName);
            if (entity != null)
            {
                entity.Value = value;
                await _workFlowPaperDataRepository.UpdateAsync(entity);
            }
            else
            {
                var data = new WorkFlowPaperData { PaperId = paperId, FieldName = fieldName, Value = value };
                await _workFlowPaperDataRepository.InsertAsync(data);
            }
        }
    }
}
